#include <iostream>

template <typename T>
void Swap(T &a, T &b);

typedef struct job {
    char name[40];
    double salary;
    int floor;
} job;

template <>
void Swap<job>(job &a, job &b);//explict specialization for job struct

void Show(job &j);

void SetFloatPrintStyle();

void doTwoSwapTest();

int main(int argc, const char** argv) 
{
    doTwoSwapTest();
    return 0;
}

void doTwoSwapTest()
{

    SetFloatPrintStyle();

    int i = 10, j = 20;
    using namespace std;
    cout << "i, j =" << i << ", " << j << ".\n";
    cout << "Using Compiler-generated in swapper:\n";
    Swap(i ,j);         //matches original template
    cout << "Now i, j =" << i << ", " << j << ".\n";

    job sue = {"Susan Yafee", 73000.60, 7};
    job sidney = {"Sidney Tafee", 78060.72, 9};

    cout << "Before job swapping: \n";
    Show(sue);
    Show(sidney);

    Swap(sue, sidney);  //matches explict specialization
    cout << "After job swapping: \n";

    Show(sue);
    Show(sidney);
}

template <typename T>
void Swap(T &a, T &b)
{
    T temp = a;
    a = b;
    b = temp;
}

template <>
void Swap(job &a, job &b)
{
    //only swap salary and floor 
    double temp_s = a.salary;
    a.salary = b.salary;
    b.salary = temp_s;

    int temp_f = a.floor;
    a.floor = b.floor;
    b.floor = temp_f;
}


void Show(job &j)
{
    using namespace std;
    cout << j.name << ": $" << j.salary
        << " on floor " << j.floor << endl;
}

void SetFloatPrintStyle()
{
    using namespace std;
    cout.precision(2);
    cout.setf(ios::fixed, ios::floatfield);
}